#include "generateModel.h"

#include "AggregationFunctionModelGenerator.h"
#include "ArithmeticOperationModelGenerator.h"
#include "OneStepOnePassDbOperationModel.h"
#include "TwoStepOnePassDbOperationModel.h"
#include "ThreeStepOnePassDbOperationModel.h"
#include "ExperimantalModel.h"

namespace jm4bbx {

	std::string generateAggregationFunctionModel(
		const int N, // parallelism level
		const std::string& lineEnd,
		const std::string& inputBoxName,
		const InputBoxConfiguration& inpBoxConf,
		const std::string& aggFunBoxName,
		const std::string& resultBoxName,
		const std::string& outputBoxName) {

			AggregationFunctionModelGenerator mg(N, inputBoxName, inpBoxConf, 
				aggFunBoxName, resultBoxName, outputBoxName);

			return mg.generateModel(lineEnd);
	}

	std::string generateArithmeticOperationModel(
		const int N, // parallelism level
		const std::string& lineEnd,
		const std::string& inputBoxName,
		const InputBoxConfiguration& firstInpBoxConf,
		const InputBoxConfiguration& secondInpBoxConf,
		const std::string& operationBoxName,
		const std::string& outputBoxName,
		const std::string& typeName) {

			ArithmeticOperationModelGenerator mg(N, inputBoxName, 
				firstInpBoxConf, secondInpBoxConf, operationBoxName, 
				outputBoxName, typeName);

			return mg.generateModel(lineEnd);
	}

	std::string generateOneStepOnePassDbOperationModel(
		const int N, // parallelism level
		const std::string& lineEnd,
		const std::string& inputBoxName,
		const InputBoxConfiguration& inpBoxConf,
		const std::string& actionBoxName,
		const std::string& outputBoxName,
		const std::string& outputForm,
		const std::string& typeName) {

			OneStepOnePassDbOperationModel mg(N, inputBoxName, inpBoxConf,
				actionBoxName, outputBoxName, outputForm, typeName);

			return mg.generateModel(lineEnd);

	}

	std::string generateTwoStepOnePassDbOperationModel(
		int N, // parallelism level
		const std::string& lineEnd,
		const std::string& inputBoxName,
		const InputBoxConfiguration& firstInpBoxConf,
		const InputBoxConfiguration& secondInpBoxConf,
		const std::string& hashBoxName,
		const std::string& actionBoxName,
		const std::string& outputBoxName,
		const std::string& outputForm,
		const std::string& typeName,
		const bool bagVersion) {

			TwoStepOnePassDbOperationModel mg(N, inputBoxName, firstInpBoxConf, 
				secondInpBoxConf, hashBoxName, actionBoxName, outputBoxName, 
				outputForm, typeName, bagVersion);

			return mg.generateModel(lineEnd);
	}

	std::string generateThreeStepOnePassDbOperationModel(
		const int N, // parallelism level
		const std::string& lineEnd,
		const std::string& inputBoxName,
		const InputBoxConfiguration& firstInpBoxConf,
		const InputBoxConfiguration& secondInpBoxConf,
		const std::string& hashBoxName,
		const std::string& actionBoxName,
		const std::string& outputBoxName,
		const std::string& outputForm,
		const std::string& typeName,
		const bool bagVersion,
		const std::string& resultCreatorBoxName) {

			ThreeStepOnePassDbOperationModel mg(N, inputBoxName, firstInpBoxConf, 
				secondInpBoxConf, hashBoxName, actionBoxName, outputBoxName, 
				outputForm, typeName, bagVersion, resultCreatorBoxName);

			return mg.generateModel(lineEnd);
	}

	std::string generateExperimentalModel(
		const int N, // parallelism level
		const std::string& lineEnd,
		const std::string& inputBoxName,
		const InputBoxConfiguration& firstInpBoxConf,
		const InputBoxConfiguration& secondInpBoxConf,
		const std::string& operationBoxName,
		const std::string& outputBoxName,
		const std::string& outputForm,
		const std::string& typeName,
		const bool bagVersion) {
			ExperimentalModel mg(N, inputBoxName, firstInpBoxConf, 
				secondInpBoxConf, operationBoxName, outputBoxName, outputForm, 
				typeName, bagVersion);
			return  mg.generateModel(lineEnd);
		}

} // namespace jm4bbx
